package com.miaosmart.config;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.miaosmart.dto.MessageDTO;
import lombok.RequiredArgsConstructor;
import org.springframework.ai.chat.memory.ChatMemory;
import org.springframework.ai.chat.messages.Message;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.util.Collections;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.TimeUnit;

@Service
@RequiredArgsConstructor
public class RedisChatMemory implements ChatMemory {

    // Redis 模板
    private final StringRedisTemplate stringRedisTemplate;

    // JSON序列化工具
    private final ObjectMapper objectMapper;

    // Redis键前缀，用于区分不同类型的键
    private final static String PREFIX = "redisChatMemory:";

    private final static long DEFAULT_EXPIRATION = 30L; // 默认过期时间1小时


    @Override
    public void add(String conversationId, List<Message> messages) {
        if (messages == null || messages.isEmpty()) {
            return;
        }

        try {
            String key = PREFIX + conversationId;
            List<String> messageJsonList = messages.stream()
                .map(MessageDTO::new)
                .map(msg -> {
                    try {
                        return objectMapper.writeValueAsString(msg);
                    } catch (JsonProcessingException e) {
                        throw new RuntimeException("消息序列化失败", e);
                    }
                })
                .toList();

            stringRedisTemplate.opsForList().leftPushAll(key, messageJsonList);
            stringRedisTemplate.expire(key, DEFAULT_EXPIRATION, TimeUnit.DAYS);
        } catch (Exception e) {
            throw new RuntimeException("添加聊天记录失败", e);
        }
    }

    @Override
    public List<Message> get(String conversationId, int lastN) {
        try {
            List<String> messages = Optional.ofNullable(
                stringRedisTemplate.opsForList().range(PREFIX + conversationId, 0, lastN - 1)
            ).orElse(Collections.emptyList());

            return messages.stream()
                .map(json -> {
                    try {
                        return objectMapper.readValue(json, MessageDTO.class);
                    } catch (JsonProcessingException e) {
                        throw new RuntimeException("消息反序列化失败", e);
                    }
                })
                .map(MessageDTO::toMessage)
                .toList();
        } catch (Exception e) {
            throw new RuntimeException("获取聊天记录失败", e);
        }
    }

    @Override
    public void clear(String conversationId) {
        try {
            stringRedisTemplate.delete(PREFIX + conversationId);
        } catch (Exception e) {
            throw new RuntimeException("清除聊天记录失败", e);
        }
    }
}
